package cn.jh.clearing.pojo;

import cn.jh.common.utils.DateUtil;
import com.google.common.collect.Lists;
import io.jsonwebtoken.lang.Strings;
import org.springframework.data.jpa.domain.Specification;

import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List;

import static io.jsonwebtoken.lang.Strings.hasText;

/**
 * @author Yichuan
 * @version 1.0
 */
public class PaymentQueryCriteria {

    private Long user_id;
    private String start_time;
    private String end_time;
    private String order_code;
    private String out_order_code;
    private String status;
    private String type = "0";
    private String phone;
    private Long brand_id;
    private String auto_clearing;
    private String third_order_code;
    private String channel_tag;
    private String order_desc_code;

    public Long getUser_id() {
        return user_id;
    }

    public void setUser_id(Long user_id) {
        this.user_id = user_id;
    }

    public String getStart_time() {
        return start_time;
    }

    public void setStart_time(String start_time) {
        this.start_time = start_time;
    }

    public String getEnd_time() {
        return end_time;
    }

    public void setEnd_time(String end_time) {
        this.end_time = end_time;
    }

    public String getOrder_code() {
        return order_code;
    }

    public void setOrder_code(String order_code) {
        this.order_code = order_code;
    }

    public String getOut_order_code() {
        return out_order_code;
    }

    public void setOut_order_code(String out_order_code) {
        this.out_order_code = out_order_code;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Long getBrand_id() {
        return brand_id;
    }

    public void setBrand_id(Long brand_id) {
        this.brand_id = brand_id;
    }

    public String getAuto_clearing() {
        return auto_clearing;
    }

    public void setAuto_clearing(String auto_clearing) {
        this.auto_clearing = auto_clearing;
    }

    public String getThird_order_code() {
        return third_order_code;
    }

    public void setThird_order_code(String third_order_code) {
        this.third_order_code = third_order_code;
    }

    public String getChannel_tag() {
        return channel_tag;
    }

    public void setChannel_tag(String channel_tag) {
        this.channel_tag = channel_tag;
    }

    public String getOrder_desc_code() {
        return order_desc_code;
    }

    public void setOrder_desc_code(String order_desc_code) {
        this.order_desc_code = order_desc_code;
    }

    /**
     * 根据查询参数拼接查询需要的条件
     */
    public Specification<PaymentOrder> getSpecification() {
        return  (root, criteriaQuery, cb) -> {
            Predicate predicate = null;
            if (getUser_id() != null) {
                Path<Long> userIdPath = root.get("userid");
                predicate = cb.equal(userIdPath, getUser_id());
            }
            if (hasText(getOrder_code())) {
                Path<String> orderCodePath = root.get("ordercode");
                predicate = predicate != null ? cb.and(predicate, cb.equal(orderCodePath, getOrder_code())) : cb.equal(orderCodePath, getOrder_code());
            }
            if (hasText(getOut_order_code())) {
                Path<String> outOrderCodePath = root.get("outMerOrdercode");
                predicate = predicate != null ? cb.and(predicate, cb.equal(outOrderCodePath, getOut_order_code())) : cb.equal(outOrderCodePath, getOut_order_code());
            }
            if (hasText(getType())) {
                Path<String> typePath = root.get("type");
                if (getType().contains(",")) {
                    List<String> typeList = Lists.newArrayList(getType().split(","));
                    predicate = predicate != null ? cb.and(predicate, typePath.in(typeList)) : typePath.in(typeList);
                } else {
                    predicate = predicate != null ? cb.and(predicate, cb.equal(typePath, getType())) : cb.equal(typePath, getType());
                }
            }
            if (hasText(getStatus())) {
                Path<String> statusPath = root.get("status");
                if (getStatus().contains(",")) {
                    List<String> statusList = Lists.newArrayList(getStatus().split(","));
                    predicate = predicate != null ? cb.and(predicate, statusPath.in(statusList)) : statusPath.in(statusList);
                } else {
                    predicate = predicate != null ? cb.and(predicate, cb.equal(statusPath, getStatus())) : cb.equal(statusPath, getStatus());
                }
            }
            Date startTime = null;
            if (Strings.hasText(getStart_time())) {
                startTime = DateUtil.getDateFromStr(getStart_time());
            }
            Date endTime = null;
            if (Strings.hasText(getEnd_time())) {
                endTime = DateUtil.getDateFromStr(getEnd_time());
            }
            Path<Date> createTimePath = root.get("createTime");
            if (startTime != null && endTime != null) {
                predicate = predicate != null ? cb.and(predicate, cb.between(createTimePath, startTime, endTime)) : cb.between(createTimePath, startTime, endTime);
            } else {
                if (startTime != null) {
                    predicate = predicate != null ? cb.and(predicate, cb.greaterThanOrEqualTo(createTimePath, startTime)) : cb.greaterThanOrEqualTo(createTimePath, startTime);
                } else if (endTime != null) {
                    predicate = predicate != null ? cb.and(predicate, cb.lessThanOrEqualTo(createTimePath, endTime)) : cb.lessThanOrEqualTo(createTimePath, endTime);
                }
            }
            if (hasText(getPhone())) {
                Path<String> phonePath = root.get("phone");
                predicate = predicate != null ? cb.and(predicate, cb.equal(phonePath, getPhone())) : cb.equal(phonePath, getPhone());
            }
            if (getBrand_id() != null) {
                Path<Long> brandIdPath = root.get("brandid");
                predicate = predicate != null ? cb.and(predicate, cb.equal(brandIdPath, getBrand_id())) : cb.equal(brandIdPath, getBrand_id());
            }
            if (hasText(getAuto_clearing())) {
                Path<String> clearingPath = root.get("autoClearing");
                if (getAuto_clearing().contains(",")) {
                    List<String> clearingList = Lists.newArrayList(getAuto_clearing().split(","));
                    predicate = predicate != null ? cb.and(predicate, clearingPath.in(clearingList)) : clearingPath.in(clearingList);
                } else {
                    predicate = predicate != null ? cb.and(predicate, cb.equal(clearingPath, getAuto_clearing())) : cb.equal(clearingPath, getAuto_clearing());
                }
            }
            if (hasText(getThird_order_code())) {
                Path<String> thirdOrderCodePath = root.get("thirdOrdercode");
                predicate = predicate != null ? cb.and(predicate, cb.equal(thirdOrderCodePath, getThird_order_code())) : cb.equal(thirdOrderCodePath, getThird_order_code());
            }
            if (hasText(getChannel_tag())) {
                Path<String> channelPath = root.get("channelTag");
                if (getChannel_tag().contains(",")) {
                    List<String> channelList = Lists.newArrayList(getChannel_tag().split(","));
                    predicate = predicate != null ? cb.and(predicate, channelPath.in(channelList)) : channelPath.in(channelList);
                } else {
                    predicate = predicate != null ? cb.and(predicate, cb.equal(channelPath, getChannel_tag())) : cb.equal(channelPath, getChannel_tag());
                }
            }
            if (hasText(getOrder_desc_code())) {
                Path<String> descCodePath = root.get("descCode");
                if (getOrder_desc_code().contains(",")) {
                    List<String> descCodeList = Lists.newArrayList(getOrder_desc_code().split(","));
                    predicate = predicate != null ? cb.and(predicate, descCodePath.in(descCodeList)) : descCodePath.in(descCodeList);
                } else {
                    predicate = predicate != null ? cb.and(predicate, cb.equal(descCodePath, getOrder_desc_code())) : cb.equal(descCodePath, getOrder_desc_code());
                }
            }
            criteriaQuery.groupBy();
            return predicate;
        };
    }
}
